<template>
  <div ref="xterm" class="xterm-box" :style="styleVar" />
</template>

<script>
/**
 * @Version 1.0.0
 * @Author DemoHui
 * @Date 2022/11/09
 */

// npm install xterm
// npm install xterm-addon-fit
import "xterm/css/xterm.css";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";

export default {
  name: "Xterm",
  props: {
    // 通过父组件传递登录ip
    hostIp: {
      type: String,
      default: "",
    },
    hostPort: {
      type: String,
      default: "",
    },
    userName: {
      type: String,
      default: "",
    },
    password: {
      type: String,
      default: "",
    },
    height: {
      // xterm显示屏幕，高度
      type: Number,
      default: 100,
    },
  },
  data() {
    return {
      fit: null,
      term: null,
      ws: null,
      terminalOptions: {
        fontSize: 18,
        convertEol: true, // 启用时，光标将设置为下一行的开头
        rendererType: "canvas", // 渲染类型
        cursorBlink: true, // 光标闪烁
        disableStdin: false, // 是否应禁用输入
        theme: {
          foreground: "#00FF00", // 字体颜色
          background: "#060101", // 背景色
          cursor: "help", // 设置光标
        },
        cursorStyle: "bar", // 光标样式  null | 'block' | 'underline' | 'bar'
        // tabStopWidth: 8, //制表宽度
        // screenKeys: true
        // cols: 98,
        // rows: 38
      },
      // loginOptions: {
      //   operate: "connect",
      //   host: "118.31.77.155", // IP
      //   port: "6222", // 端口号
      //   username: "root", // 用户名
      //   password: "simon1237***Gfc" // 密码
      // },
    };
  },
  computed: {
    // 动态设置xterm显示屏幕高度
    styleVar() {
      return {
        "--terminal-height": this.height + "vh",
      };
    },
  },
  // created() {
  //   // 初始化链接
  //   this.initTerm();
  //   this.initSocket();
  // },
  beforeDestroy() {
    // 退出销毁链接
    this.ws.close();
    this.term.dispose();
  },
  methods: {
    startConnect() {
      // 初始化链接
      this.initTerm();
      this.initSocket();
    },
    stopConnect() {
      // 断开链接
      this.ws.close();
      this.term.dispose();
    },
    // 初始化Terminal
    initTerm() {
      this.term = new Terminal(this.terminalOptions);
      this.fit = new FitAddon();
      this.term.loadAddon(this.fit);
    },
    initSocket() {
      // 初始化Websocket
      this.ws = new WebSocket("ws://127.0.0.1:8089/webssh");

      this.ws.onopen = this.wsOnOpen;
      this.ws.onmessage = this.wsOnMessage;
      this.ws.onclose = this.wsOnClose;

      this.term.onData(this.termOnData);
      // this.term.onResize(this.termOnResize)

      window.onresize = () => this.fit.fit();
    },
    wsOnOpen() {
      // console.log('ws 建立连接')
      this.ws.send(
        JSON.stringify({
          operate: "connect",
          host: this.hostIp, // IP
          port: this.hostPort, // 端口号
          username: this.userName, // 用户名
          password: this.password, // 密码
        })
      );
      this.term.open(this.$refs.xterm);
      this.term.writeln(
        [
          "",
          "                                  \x1b[31;1m欢迎使用远程终端\x1b[0m",
          "",
        ].join("\n\r")
      );
      // this.term.writeln('\x1b[33;1m////////////////////////////////////////////////////////////////////\n' +
      //   '//                          _ooOoo_                               //\n' +
      //   '//                         o8888888o                              //\n' +
      //   '//                         88" . "88                              //\n' +
      //   '//                         (| ^_^ |)                              //\n' +
      //   '//                         O\\  =  /O                              //\n' +
      //   '//                      ____/`---\'\\____                           //\n' +
      //   '//                    .\'  \\\\|     |//  `.                         //\n' +
      //   '//                   /  \\\\|||  :  |||//  \\                        //\n' +
      //   '//                  /  _||||| -:- |||||-  \\                       //\n' +
      //   '//                  |   | \\\\\\  -  /// |   |                       //\n' +
      //   '//                  | \\_|  \'\'\\---/\'\'  |   |                       //\n' +
      //   '//                  \\  .-\\__  `-`  ___/-. /                       //\n' +
      //   '//                ___`. .\'  /--.--\\  `. . ___                     //\n' +
      //   '//              ."" \'<  `.___\\_<|>_/___.\'  >\'"".                  //\n' +
      //   '//            | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |                 //\n' +
      //   '//            \\  \\ `-.   \\_ __\\ /__ _/   .-` /  /                 //\n' +
      //   '//      ========`-.____`-.___\\_____/___.-`____.-\'========         //\n' +
      //   '//                           `=---=\'                              //\n' +
      //   '//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //\n' +
      //   '//             \x1b[36m佛祖保佑       永不宕机      永无BUG\x1b[0m               \x1b[33;1m//\n' +
      //   '////////////////////////////////////////////////////////////////////\x1b[0m')
      this.term.writeln(`

           ██████╗ ██████╗ ███╗   ██╗███╗   ██╗███████╗ ██████╗████████╗
          ██╔════╝██╔═══██╗████╗  ██║████╗  ██║██╔════╝██╔════╝╚══██╔══╝
          ██║     ██║   ██║██╔██╗ ██║██╔██╗ ██║█████╗  ██║        ██║
          ██║     ██║   ██║██║╚██╗██║██║╚██╗██║██╔══╝  ██║        ██║
          ╚██████╗╚██████╔╝██║ ╚████║██║ ╚████║███████╗╚██████╗   ██║
           ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═╝

      `);
      this.term.writeln("登录时间为：" + new Date().toLocaleString());
      this.term.writeln("请输入`help`以获取一个命令列表");
      this.term.write("连接中...\r");
      this.term.focus();
      this.fit.fit();
    },
    wsOnMessage(res) {
      // console.log('ws 收到消息', res)
      this.term.write(res.data.toString());
    },
    wsOnClose() {
      //连接关闭回调
      this.term.write("\r连接已关闭");
    },
    termOnData(data) {
      this.ws.send(
        JSON.stringify({
          operate: "command",
          command: data,
        })
      );
    },
    termOnResize({ cols, rows }) {
      this.ws.send(
        JSON.stringify({
          resize: [cols, rows],
        })
      );
    },
  },
};
</script>

<style lang="scss" scoped>
.xterm-box {
  width: 100%;
  height: calc(100vh - 160px); //调整终端高度
  background: #000000;
  overflow-y: auto;
}
</style>
